#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "jogador.h"
#include "humano.h"
#include "computador.h"
#include "campo.h"
#include "util.h"

#define TAM_MAX 23

void jogar();
void abrirCasa(Campo, Pos, Jogador*);
void abrirCasaSemNada(Campo, Pos, Jogador*);
void imprimirStatus();
void telaAbertura();
void telaFinalizacao();

Campo campo;
Jogador *atual;
int acertosParaGanhar;
long tempoInicial;
Jogador humano, computador;

int main() {

	telaAbertura();

	int jogarNovamente;

	do {
		limparTela();

		int n;

		n = leInteiro("Qual o tamanho do tabuleiro?", 2, TAM_MAX,
				"Tamanho invalido.");
		campo = alocarCampo(n);

		if (!campo.tamanho) {
			printf("Sem memoria!\n");
			return EXIT_FAILURE;
		}

		montarCampo(campo);
		pausarTela();

		jogar();

		desalocarCampo(campo);
		pausarTela();
		limparTela();

		jogarNovamente = leInteiro("Deseja jogar novamente? (n/s) ", 0, 1,
				"Resposta invalida.");
	} while (jogarNovamente);

	telaFinalizacao();

	return EXIT_SUCCESS;
}

void jogar() {

	time(&tempoInicial);
	acertosParaGanhar = (campo.totBombas / 2) + 1;

	humano = criarHumano();
	iniciarJogador(humano);

	computador = criarComputador();
	iniciarJogador(computador);

	int venceu = 0;

	atual = &humano;
	Pos pos;

	while (!venceu) {
		do {
			imprimirStatus();
			printf("Vez de %s\n", atual->nome);

			pos = atual->jogar(campo);

			abrirCasa(campo, pos, atual);

			imprimirStatus();
			printf("%s realizou jogada na posicao (%i,%i)... \n", atual->nome,
					pos.m, pos.n);
			pausarTela();

			if (atual->acertos >= acertosParaGanhar) {
				venceu = 1;
				break;
			}
		} while (getCasa(campo, pos)->tipoCasa == atual->casaBomba);

		atual = (atual == &humano) ? &computador : &humano;
	}

	printf("%s ganhou!\n", humano.acertos > computador.acertos ? humano.nome
			: computador.nome);
}

void abrirCasa(Campo campo, Pos pos, Jogador *jogador) {
	Casa * casa = getCasa(campo, pos);

	if (casa->visivel) {
		return;
	}

	casa->visivel = 1;
	if (casa->tipoCasa == zero) {
		Pos posAdjacente;
		posAdjacente.m = pos.m - 1;
		for (posAdjacente.n = pos.n - 1; posAdjacente.n <= pos.n + 1; posAdjacente.n++) {
			abrirCasa(campo, posAdjacente, jogador);
		}

		posAdjacente.m = pos.m + 1;
		for (posAdjacente.n = pos.n - 1; posAdjacente.n <= pos.n + 1; posAdjacente.n++) {
			abrirCasa(campo, posAdjacente, jogador);
		}

		posAdjacente.m = pos.m;
		posAdjacente.n = pos.n - 1;
		abrirCasa(campo, posAdjacente, jogador);
		posAdjacente.n = pos.n + 1;
		abrirCasa(campo, posAdjacente, jogador);
	} else if (casa->tipoCasa == bomba) {
		jogador->acertos++;
		casa->tipoCasa = jogador->casaBomba;
	}
}

void imprimirStatus() {
	limparTela();
	printf("%s: [%d/%d]\n", humano.nome, humano.acertos, acertosParaGanhar);
	printf("%s: [%d/%d]\n", computador.nome, computador.acertos,
			acertosParaGanhar);
	printf("Minas restantes: %i\n", campo.totBombas - humano.acertos - computador.acertos);
	printf("Tempo de jogo: %lis\n", (time(NULL) - tempoInicial));
	printf("\n\n");
	imprimirCampo(campo);
	printf("\n\n");
}

void telaAbertura() {
	printf("UFCG - Universidade Federal de Campina Grande\n");
	printf("DSC - Departamento de Sistemas e Computacao\n");
	printf("CCC - Curso de Ciencia da Computacao\n");
	printf("\n");
	printf("Disciplina: Paradigmas de Linguagens de Programacao\n");
	printf("Professor: Franklin Ramalho\n");
	printf("Periodo 2008.1\n");
	printf("\n\n");
	printf(
			"   ___                                     _                 _       \n");
	printf(
			"  / __\\__ _ _ __ ___  _ __   ___     /\\/\\ (_)_ __   __ _  __| | ___  \n");
	printf(
			" / /  / _` | '_ ` _ \\| '_ \\ / _ \\   /    \\| | '_ \\ / _` |/ _` |/ _ \\ \n");
	printf(
			"/ /___ (_| | | | | | | |_) | (_) | / /\\/\\ \\ | | | | (_| | (_| | (_) |\n");
	printf(
			"\\____/\\__,_|_| |_| |_| .__/ \\___/  \\/    \\/_|_| |_|\\__,_|\\__,_|\\___/ \n");
	printf("   __ _              |_|                                 ___  \n");
	printf("  / /(_)_ __   __ _ _   _  __ _  __ _  ___ _ __ ___     / __\\\n");
	printf(
			" / / | | '_ \\ / _` | | | |/ _` |/ _` |/ _ \\ '_ ` _ \\   / /    \n");
	printf("/ /___ | | | | (_| | |_| | (_| | (_| |  __/ | | | | | / /___  \n");
	printf(
			"\\____/_|_| |_|\\__, |\\__,_|\\__,_|\\__, |\\___|_| |_| |_| \\____/  \n");
	printf("              |___/             |___/                         \n");
	printf("\n\n");
	printf("Equipe:\n");
	printf("Ana Gabrielle Falcao\n");
	printf("Fabiano Miranda\n");
	printf("Paulo Ricardo Motta\n");
	printf("Renato Miceli\n");
	printf("\n\n");
	printf("Campina Grande, 22/07/2008\n");
	printf("\n\n");
	pausarTela();
	limparTela();
}

void telaFinalizacao() {
	limparTela();
	printf("                              )                 \n");
	printf(" (                         ( /(                 \n");
	printf(" )\\ )      )    )     (    )\\())  )     (  (    \n");
	printf("(()/(   ( /(   (     ))\\  ((_)\\  /((   ))\\ )(   \n");
	printf(" /(_))_ )(_))  )\\  '/((_)   ((_)(_))\\ /((_)()\\  \n");
	printf("(_)) __((_)_ _((_))(_))    / _ \\_)((_)_))  ((_) \n");
	printf("  | (_ / _` | '  \\() -_)  | (_) \\ V // -_)| '_| \n");
	printf("   \\___\\__,_|_|_|_|\\___|   \\___/ \\_/ \\___||_|   \n");
	printf("\n\n\n");
	pausarTela();
}
